<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style type="text/css">
    #box {
      width: 100px;
      height: 100px;
      background-color: red;
      padding: 10px;
      border: 10px solid yellow;
    }
    #box3 {
      width: 200px;
      height: 300px;
      background-color: aqua;
      overflow: auto;
    }
    #box4 {
      width: 150px;
      height: 500px;
      background-color: #bfa;
    }
  </style>
  <script type="text/javascript">
    window.onload = function() {
      const box = document.getElementById('box')
      const box3 = document.getElementById('box3')
      const btn = document.getElementById('btn')
      const btn1 = document.getElementById('btn1')
      btn1.addEventListener('click', function() {
        console.log(this)
      })
      btn.onclick = function() {
        /*
        * clientWidth clientHeight
        * - 可以获取元素的可见宽度和高度，包括内容区和内边距
        * - 这些属性都是不带px的，返回都是一个数字，可以直接进行计算
        * - 这些属性都是只读的，不能修改
        */
        console.log(box.clientWidth, box.clientHeight)

        /*
        * offsetWidth offsetHeight
        * 	- 获取元素的整个的宽度和高度，包括内容区、内边距和边框
        */
        console.log(box.offsetWidth, box.offsetHeight)

        /*
        * offsetParent
        * 	- 可以用来获取当前元素的定位父元素
        *   - 会获取到离当前元素最近的开启了定位的祖先元素,如果所有的祖先元素都没有开启定位，则返回body
        */
        let op = box.offsetParent
        console.log(op.id) // box2

        /*
        * offsetLeft
        * 	- 当前元素相对于其定位父元素的水平偏移量
        * offsetTop
        * 	- 当前元素相对于其定位父元素的垂直偏移量
        */

        /*
        * scrollWidth scrollHeight
        * 	- 可以获取元素整个滚动区域的宽度和高度
        */
        console.log(box3.clientHeight, box3.scrollHeight)

        /*
        * scrollLeft
        * 	- 可以获取水平滚动条滚动的距离
        * scrollTop
        * 	- 可以获取垂直滚动条滚动的距离
        */

        // 当满足scrollHeight - scrollTop === clientHeight,说明垂直滚动条滚动到底了
        // 当满足scrollWidth - scrollLeft === clientWidth,说明水平滚动条滚动到底

        // 可以将事件对象的cancelBubble设置为true，即可取消冒泡
        // event.cancelBubble = true;

        /*
				 * addEventListener()
				 * 	- 通过这个方法可以为元素绑定响应函数
				 *  - 参数：
				 * 		1.事件的字符串，不要on
				 * 		2.回调函数，当事件触发时该函数会被调用
				 * 		3.是否在捕获阶段触发事件，需要一个布尔值，一般都传false
				 * 
				 * 使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数，当事件被触发时，响应函数将会按照函数的绑定顺序执行
				 * 这个方法不支持IE8及以下的浏览器
				 */

        /*
				 * attachEvent()
				 * 	- 在IE8中可以使用attachEvent()来绑定事件
				 *  - 参数：
				 * 		1.事件的字符串，要on
				 * 		2.回调函数
				 * 
				 *  - 这个方法可以同时为一个事件绑定多个处理函数，不同的是它是后绑定先执行，执行顺序和addEventListener()相反
				 */
      }

      // 定义一个函数，用来为指定元素绑定响应函数
			/*
			 * addEventListener()中的this，是绑定事件的对象
			 * attachEvent()中的this，是window
			 *  需要统一两个方法this
			 */
			/*
			 * 参数：
			 * 	obj 要绑定事件的对象
			 * 	eventStr 事件的字符串(不要on)
			 *  callback 回调函数
			 */
			function bind(obj, eventStr, callback) {
				if(obj.addEventListener) {
					// 大部分浏览器兼容的方式
					obj.addEventListener(eventStr, callback, false)
				} else {
					/*
					 * this是由调用方式决定
					 * callback.call(obj)
					 */
					// IE8及以下
					obj.attachEvent('on' + eventStr, function() {
						// 在匿名函数中调用回调函数
						callback.call(obj)
					})
				}
			}
    }
  </script>
</head>
<body>
  <div id="box2" style="position: relative;">
    <div id="box"></div>
  </div>
  <br>
  <button id="btn">点我</button>
  <button id="btn1">点我呀</button>
  <div id="box3">
    <div id="box4"></div>
  </div>
</body>
</html>